package xyz.mrkwcode.aiimusicserver.controllers;

import com.alibaba.fastjson.JSONObject;
import org.checkerframework.checker.units.qual.C;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import xyz.mrkwcode.aiimusicserver.DAOs.CreatorMapper;
import xyz.mrkwcode.aiimusicserver.annos.ResponseResult;
import xyz.mrkwcode.aiimusicserver.exceptions.UniverCustomException;
import xyz.mrkwcode.aiimusicserver.pojos.*;
import xyz.mrkwcode.aiimusicserver.services.OtherService;
import xyz.mrkwcode.aiimusicserver.services.UserService;
import xyz.mrkwcode.aiimusicserver.utils.TcosUtil.TcosUtil;
import xyz.mrkwcode.aiimusicserver.utils.ThreadLocalUtil;
import xyz.mrkwcode.aiimusicserver.utils.TimeUtil;

import java.io.IOException;
import java.sql.Timestamp;
import java.time.Instant;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.time.format.DateTimeFormatter;
import java.util.*;

@RestController
@RequestMapping("/api")
@Validated
@ResponseResult
public class OtherController {
    @Autowired
    private OtherService otherService;

    @Autowired
    private UserService userService;

    @Autowired
    private CreatorMapper creatorMapper;

    private static final String COS_CAVATAR_PATH = "aii-music/creatoravatar/";

    @GetMapping("/tasklist")
    public List<UserTask> findAllTaskList(@RequestParam(required = false) Integer uid) {
        List<UserTask> tasks = otherService.findAllTaskList(uid);
        return tasks;
    }

    @PatchMapping("/banuser")
    public void banUser(@RequestParam Integer taskid) {
        Map<String, Object> map = ThreadLocalUtil.get();
        Integer uid = (Integer) map.get("uid");
        User loginUser = userService.findByUid(uid);
        if(!loginUser.getPermission().equals("admin")) {
            throw new UniverCustomException(500, "您没有权限禁用账户");
        } else {
            UserTask userTask = otherService.findTaskByTaskId(taskid);
            otherService.banUser(userTask);
        }
    }

    @PostMapping("/admin/creator")
    public void addCreator(@RequestParam String creatorname,
                           @RequestParam String gender,
                           @RequestParam("creatorAvatar") MultipartFile creatoravatar,
                           @RequestParam String birthstr,
                           @RequestParam(required = false) String location,
                           @RequestParam(required = false) String introduction) throws IOException {
        Map<String, Object> map = ThreadLocalUtil.get();
        Integer uid = (Integer) map.get("uid");
        User loginUser = userService.findByUid(uid);
        if(!loginUser.getPermission().equals("admin")) {
            throw new UniverCustomException(500, "您没有权限添加创作者");
        } else {
            String avatarUrl = "";
            if(!creatoravatar.isEmpty()) {
                String avatarOriginalFilename = creatoravatar.getOriginalFilename();
                String avatarFilename = avatarOriginalFilename.substring(0, avatarOriginalFilename.lastIndexOf(".")) + "_" + UUID.randomUUID().toString() + avatarOriginalFilename.substring(avatarOriginalFilename.lastIndexOf("."));
                avatarUrl = TcosUtil.uploadFile(COS_CAVATAR_PATH, avatarFilename, creatoravatar.getInputStream());
            } else {
                throw new UniverCustomException(500, "头像文件不能为空");
            }

            DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
            Instant instant = Instant.ofEpochSecond(Long.parseLong(birthstr));
            String birthTimestamp = formatter.format(LocalDateTime.ofInstant(instant, ZoneId.systemDefault()));
            Timestamp birthTime = Timestamp.valueOf(birthTimestamp);

            Creator creator = new Creator();
            creator.setCreatorname(creatorname);
            creator.setGender(gender);
            creator.setCreatorAvatar(avatarUrl);
            creator.setBirth(birthTime);
            if(location != null && !location.isEmpty()) {
                creator.setLocation(location);
            }
            if(introduction != null && !introduction.isEmpty()) {
                creator.setIntroduction(introduction);
            }
            creatorMapper.addCreator(creator);
        }
    }

    @GetMapping("/admin/creator")
    public PageBean<Creator> findCreatorByName(Integer pageNum,
                                               @RequestParam(required = false) Integer pageSize,
                                               @RequestParam(required = false) String creatorname) {
        return otherService.findCreatorByName(pageNum, Objects.requireNonNullElse(pageSize, 20), creatorname);
    }

    @PatchMapping("/admin/creator")
    public void editCreator(@RequestParam Integer cid,
                            @RequestParam(required = false) String creatorname,
                            @RequestParam(required = false) String gender,
                            @RequestParam(required = false) String birthstr,
                            @RequestParam(required = false) String location,
                            @RequestParam(required = false) String introduction) {
        Map<String, Object> map = ThreadLocalUtil.get();
        Integer uid = (Integer) map.get("uid");
        User loginUser = userService.findByUid(uid);
        if(!loginUser.getPermission().equals("admin")) {
            throw new UniverCustomException(500, "您没有权限编辑创作者信息");
        } else {
            if(creatorname != null && creatorname.isEmpty() &&
                    gender != null && gender.isEmpty() &&
                    birthstr != null && birthstr.isEmpty() &&
                    location!= null && location.isEmpty() &&
                    introduction != null && introduction.isEmpty()) {
                throw new UniverCustomException(500, "填入信息全为空");
            }
            Creator creator = new Creator();
            if(creatorname != null && !creatorname.isEmpty()) {
                creator.setCreatorname(creatorname);
            }
            if(gender != null && !gender.isEmpty()) {
                creator.setGender(gender);
            }
            if(birthstr != null && !birthstr.isEmpty()) {
                DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
                Instant instant = Instant.ofEpochSecond(Long.parseLong(birthstr));
                String birthTimestamp = formatter.format(LocalDateTime.ofInstant(instant, ZoneId.systemDefault()));
                Timestamp birthTime = Timestamp.valueOf(birthTimestamp);
                creator.setBirth(birthTime);
            }
            if(location != null && !location.isEmpty()) {
                creator.setLocation(location);
            }
            if(introduction != null && !introduction.isEmpty()) {
                creator.setIntroduction(introduction);
            }
            otherService.editCreator(creator);
        }
    }

    @PatchMapping("/admin/creator/avatar")
    public String editCreatorAvatar(@RequestParam Integer cid,
                                  @RequestParam MultipartFile avatarFile) throws IOException {
        Map<String, Object> map = ThreadLocalUtil.get();
        Integer uid = (Integer) map.get("uid");
        User loginUser = userService.findByUid(uid);
        if(!loginUser.getPermission().equals("admin")) {
            throw new UniverCustomException(500, "您没有权限编辑创作者信息");
        } else {
            String resOriginalFilename = avatarFile.getOriginalFilename();
            String resFilename = null;
            if (resOriginalFilename != null) {
                resFilename = resOriginalFilename.substring(0, resOriginalFilename.lastIndexOf(".")) + "_" + UUID.randomUUID().toString() + resOriginalFilename.substring(resOriginalFilename.lastIndexOf("."));
            }
            String resUrl = TcosUtil.uploadFile(COS_CAVATAR_PATH, resFilename, avatarFile.getInputStream());
            otherService.editCreatorAvatar(cid, resUrl);
            return resUrl;
        }
    }

    @DeleteMapping("/admin/creator")
    public void deleteCreator(@RequestParam Integer cid) {
        Map<String, Object> map = ThreadLocalUtil.get();
        Integer uid = (Integer) map.get("uid");
        User loginUser = userService.findByUid(uid);
        if(!loginUser.getPermission().equals("admin")) {
            throw new UniverCustomException(500, "您没有权限删除创作者");
        } else {
            Creator toDelete = creatorMapper.getCreatorByCid(cid);
            if(toDelete == null) throw new UniverCustomException(404, "该创作者不存在");
            otherService.deleteCreator(cid);
        }
    }

    @PatchMapping("/changePermission")
    public void changePermission(@RequestParam Integer taskid) {
        Map<String, Object> map = ThreadLocalUtil.get();
        Integer uid = (Integer) map.get("uid");
        User loginUser = userService.findByUid(uid);
        if(!loginUser.getPermission().equals("admin")) {
            throw new UniverCustomException(500, "您没有权限修改用户权限");
        } else {
            UserTask userTask = otherService.findTaskByTaskId(taskid);
            otherService.changePermission(userTask);
        }
    }

    @PostMapping("/comment")
    public void addComment(@RequestParam(required = false) Integer mid,
                           @RequestParam(required = false) Integer mlid,
                           @RequestParam String content) {
        if(mid == null && mlid == null) {
            throw new UniverCustomException(500, "请至少填入一个mid或mlid");
        }
        if(mid != null && mlid != null) {
            throw new UniverCustomException(500, "mlid或mid只能填入一个");
        }
        Map<String, Object> map = ThreadLocalUtil.get();
        Integer uid = (Integer) map.get("uid");
        User loginUser = userService.findByUid(uid);
        if(loginUser.getIsBanned()) throw new UniverCustomException(500, "用户被封禁不能进行评论");

        Boolean isMusiclist = mid == null;
        Comment comment = new Comment();
        comment.setUid(uid);
        comment.setIsMusiclist(isMusiclist);
        if (!isMusiclist) {
            comment.setMid(mid);
        } else {
            comment.setMlid(mlid);
        }
        comment.setContent(content.trim());
        String now = TimeUtil.dateToString(new Date(), TimeUtil.TIME_FULL_SPRIT);
        Timestamp time = Timestamp.valueOf(now);
        comment.setCreatedTime(time);
        comment.setUpdatedTime(time);
        otherService.addComment(comment);
    }


    @DeleteMapping("/comment")
    public void removeComment(@RequestParam Integer cmid) {
        Comment comment = otherService.findCommentByCmid(cmid);
        if (comment == null) throw new UniverCustomException(500, "该评论不存在");
        Map<String, Object> map = ThreadLocalUtil.get();
        Integer uid = (Integer) map.get("uid");
        User loginUser = userService.findByUid(uid);
        if(!loginUser.getPermission().equals("admin") || !comment.getUid().equals(uid)) throw new UniverCustomException(500, "非管理员禁止删除他人评论");
        otherService.removeComment(cmid);
    }

    @GetMapping("/comment")
    public PageBean<Comment> getComments(Integer pageNum,
                                        @RequestParam(required = false) Integer pageSize,
                                        @RequestParam(required = false) Integer mid,
                                        @RequestParam(required = false) Integer mlid) {
        if(mid == null && mlid == null) {
            throw new UniverCustomException(500, "请至少填入一个mid或mlid");
        }
        if(mid != null && mlid != null) {
            throw new UniverCustomException(500, "mlid或mid只能填入一个");
        }
        return otherService.getComments(pageNum, Objects.requireNonNullElse(pageSize, 20), mid, mlid);
    }

    @PostMapping("/comment/like")
    public void like(@RequestParam Integer cmid, @RequestParam Integer up) {
        Comment thisComment = otherService.findCommentByCmid(cmid);
        if (thisComment == null) throw new UniverCustomException(500, "该评论不存在");
        Comment comment = new Comment();
        comment.setCmid(cmid);
        comment.setUp(up);
        String now = TimeUtil.dateToString(new Date(), TimeUtil.TIME_FULL_SPRIT);
        Timestamp time = Timestamp.valueOf(now);
        comment.setUpdatedTime(time);
        otherService.like(comment);
    }

}
